【题解】 [JSOI2008]球形空间产生器 高斯消元 洛谷P4035 | Qiuly's blog!

【题解】 [JSOI2008]球形空间产生器 高斯消元 洛谷P4035

“你要求出这个n维球体的球心坐标“,这使我想到的解方程……

先假设n=2,这是一个二维平面。设圆心的坐标为$(x,y)$,有两个坐标$(a_1,b_1)$和$(a_2,b_2)$,显然两个坐标的关系为:

考虑如何化简上面的式子。

根据完全平方公式:

同理

整理后:

移项后:

这个式子最终为:

由于 $a_1^2-a_2^2+b_1^2-b_2^2​$ 是已知的,我们将 $a_1^2-a_2^2+b_1^2-b_2^2​$ 设为$Sum​$.

$2(a_1-a_2)​$ 和 $2(b_1-b_2)​$都是已知的项,分别设为 $a​$ 和 $b​$ .

所以它又变成了我们亲切的小学奥数之解方程:$ax+by=Sum$

对于二维的答案是 $(x,y)​$ ,$x​$ 和 $y​$ 都可以通过高斯消元的模板来解出。

对于更高的维数,跟二维同理,只不过”元”多了几个而已。

所以就这样愉快的A掉了这道大水题

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define RI register int
using namespace std;
const int N=25;
const double eps=1e-8;
double v[N][N],f[N][N],s[N],del;
int n;
inline bool Gauss(){
for(RI k=1,i=1;i<=n;++i,k=i){
for(RI j=i+1;j<=n;++j)if(abs(f[j][i])>abs(f[k][i]))k=j;
if(fabs(del=f[k][i])<eps)return false;//不判就出BUG,不知道为啥
swap(f[i],f[k]);swap(s[i],s[k]);
for(RI j=i;j<=n;++j)f[i][j]/=del;s[i]/=del;
for(k=1;k<=n;++k)if(k!=i){
del=f[k][i];
for(RI j=i;j<=n;++j)f[k][j]-=f[i][j]*del;
s[k]-=s[i]*del;
}
}return true;
}
int main(){
scanf("%d",&n);
for(RI i=1;i<=n+1;++i)for(RI j=1;j<=n;++j)scanf("%lf",&v[i][j]);
for(RI i=1;i<=n;++i)
for(RI j=1;j<=n;++j){
s[i]+=(v[i][j]*v[i][j]-v[i+1][j]*v[i+1][j]);//求上面的 "Sum"
f[i][j]=2*(v[i][j]-v[i+1][j]);//求上面的 "a"、"b"等
}
Gauss();
for(RI i=1;i<n;++i)printf("%.3lf ",s[i]);//注意输出格式!
printf("%.3lf",s[n]);
return 0;
}

这题啥都好,就是输出格式有点制杖……请各位小心……

本文标题:【题解】 [JSOI2008]球形空间产生器 高斯消元 洛谷P4035

文章作者:Qiuly

发布时间:2019年02月14日 - 00:00

最后更新:2019年03月29日 - 13:54

原始链接:http://qiulyblog.github.io/2019/02/14/[题解]luoguP4035/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。